package top.yoahh.aspect;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import top.yoahh.annotation.Dict;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * 自定义字典翻译字段
 */
@Aspect
@Slf4j
@Component
public class DictAspect {

    /**
     * 定义切点的位置
     */
    @Pointcut("execution(public * top.yoahh..*.*Controller.*(..))")
    public void executeService() {
    }

    @Around("executeService()")
    public Object doAround(ProceedingJoinPoint point) throws Throwable {
        long time1 = System.currentTimeMillis();
        Object result = point.proceed();
        long time2 = System.currentTimeMillis();
        log.info("获取JSON数据，耗时：{}ms", time2 - time1);
        long start = System.currentTimeMillis();
        // 解析输入字典翻译
        this.parseDictText(result);
        long end = System.currentTimeMillis();
        log.info("解析注入JSON数据，耗时：{}ms", end - start);
        return result;
    }

    /**
     * 本方法主要针对的是返回对象为PageInfo的分页列表数据进行动态字典注入
     * 字典注入实现原理：通过对实体类添加的注解@Dict来标识需要的字典内容，字典分为字典表code即可，table字典code,text,table配合使用
     * 示例为SysUser   字段为sex 添加了注解@Dict(dicCode = "sex") 会在字典服务立马查出来对应的text 然后在请求list的时候将这个字典text，已字段名称加_dictText形式返回到前端
     * 例输入当前返回值的就会多出一个sex_dictText字段
     * {
     *     sex:1,
     *     sex_dictText:"男"
     * }
     *
     * @param result
     * @return
     */
    private Object parseDictText(Object result) {
        // 判断是否为分页查询结果类
        if (result instanceof PageInfo) {
            List<JSONObject> items = new ArrayList<>();
            for (Object record : ((PageInfo<?>) result).getList()) {
                ObjectMapper mapper = new ObjectMapper();
                String json = "{}";

                try {
                    json = mapper.writeValueAsString(record);
                } catch (JsonProcessingException e) {
                    log.error("JSON解析失败，错误：{}", e.getMessage());
                }

                JSONObject item = JSONObject.parseObject(json);

                for (Field field : record.getClass().getDeclaredFields()) {
                    if (field.getAnnotation(Dict.class) != null) {
                        String code = field.getAnnotation(Dict.class).dicCode();
                        String text = field.getAnnotation(Dict.class).dicText();
                        String table = field.getAnnotation(Dict.class).dictTable();
                        String key = String.valueOf(item.get(field.getName()));

                        // 翻译字典对应的txt
                        String textValue = this.translateDictValue(code, text, table, key);

                        item.put(field.getName() + "_text", textValue);
                        log.info("=================>开始：翻译字典：{}<=================",key);
                        log.info("=================>结束：记录日志<=================");
                    }
                }
                items.add(item);
            }
            ((PageInfo) result).setList(items);
        }
        return result;
    }

    private String translateDictValue(String code, String text, String table, String key) {
        if (StringUtils.isEmpty(key)) {
            return null;
        }

        StringBuffer textValue = new StringBuffer();
        String[] keys = key.split(",");
        for (String k : keys) {
            String tempValue = null;
            log.debug("字典key:", k);
            if (k.trim().length() == 0) {
                continue;
            }
            if (!StringUtils.isEmpty(table)) {
                // 表外键关联字典翻译
            } else {
                // 字典表翻译
            }

            // 判断是否翻译成功
            if (tempValue != null) {
                if (!"".equals(textValue.toString())) {
                    textValue.append(",");
                }
                textValue.append(tempValue);
            }
        }

        return textValue.toString();

    }
}
